import re

from libraries.scns.script.utils import join_line, replace


def isr_updater(isr='user/isr.c', startup='libraries/sdk/Startup/startup_ch32v30x_D8C.S'):
    funcs = []
    funcs_fast = []
    stack = 0
    for line in open(isr).readlines():
        if line.startswith('#if'):
            stack += 1
        if line.startswith('#endif'):
            stack -= 1
        if stack == 0:
            match = re.search(re.compile(r'void (\w*?)\(void\) *// *fast$'), line)
            if match:
                funcs += [match.group(1)]
                funcs_fast += [match.group(1)]
            else:
                match = re.search(re.compile(r'void (\w*?)\(void\)$'), line)
                if match:
                    funcs += [match.group(1)]
    funcs = sorted(funcs, key=lambda x: (len(x), x))
    funcs_fast = set(funcs_fast)
    codes = []
    for f in funcs:
        s = f'void {f}(void)'
        fa = '"WCH-Interrupt-fast"' if f in funcs_fast else ''
        codes.append(f'{s:48s}__attribute__((interrupt({fa}),noinline,used,__used__));')
    codes.append('const IRQn_Type __fastIRqn[]={')
    codes += [f.replace('Handler', 'n,') for f in funcs_fast]
    codes.append('128,')
    codes.append('};')

    print(f'//isrReaderStart', f'//isrReaderEnd')
    replace(isr, f'//isrReaderStart', f'//isrReaderEnd', join_line(codes))
    funcs = set(funcs)
    lines = open(startup).readlines()
    for i, line in enumerate(lines):
        mw1 = re.search(r'\.weak +(.*?) +/\* (.*?) \*/', line)
        mw2 = re.search(r'(/\*)?(.*?)\:  1\:  j 1b', line)
        if mw1:
            if mw1.group(1) in funcs:
                lines[i] = f'    /*.weak   {mw1.group(1):32s}/* {mw1.group(2)} */\n'
            else:
                lines[i] = f'    .weak   {mw1.group(1):32s}/* {mw1.group(2)} */\n'
        if mw2:
            if mw2.group(2) in funcs:
                lines[i] = f'/*{mw2.group(2)}:  1:  j 1b*/\n'
            else:
                lines[i] = f'{mw2.group(2)}:  1:  j 1b\n'
    with open(startup, 'w') as f:
        f.writelines(lines)


if __name__ == '__main__':
    isr_updater()
